package hu.blok1.veilingsite.client.gui;

import hu.blok1.veilingsite.client.Veilingsite;
import hu.blok1.veilingsite.client.data.ProductService;
import hu.blok1.veilingsite.client.data.ProductServiceAsync;
import hu.blok1.veilingsite.shared.Bid;
import hu.blok1.veilingsite.shared.Product;
import hu.blok1.veilingsite.shared.User;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

public class ProductSpecificationsGUI {
	private VerticalPanel vp;
	private VerticalPanel vpContentData = new VerticalPanel();
	private ScrollPanel scroll = new ScrollPanel();

	private User user;
	private Veilingsite veilingsite;
	private Product product = new Product();

	private List<Bid> bidsOfProduct;
	private CellTable<Bid> bidsTable;

	private int price = 0;
	private Label highestBid = new Label();
	private TextBox dockWestYourBidTextBox = new TextBox();

	private DateTimeFormat dtf = DateTimeFormat
			.getFormat("dd-MM-yyyy HH:mm:ss");

	private final ProductServiceAsync ProductService = GWT
			.create(ProductService.class);

	private Label productId = new Label();
	private Label productName = new Label();
	private Label productDescription = new Label();
	private Label productCategory = new Label();
	private Label productUserId = new Label();
	private Label startDate = new Label();
	private Label endDate = new Label();

	private Button confirmBid = new Button();

	public ProductSpecificationsGUI(VerticalPanel a, Veilingsite vs, String id) {
		veilingsite = vs;
		user = veilingsite.getUser();

		vp = a;
		vp.clear();

		try {
			getProduct(id);
		} catch (Exception e) {
			e.printStackTrace();
		}

		initSearchPanel();

		if (user.isLoggedIn()) {
			confirmBid.setVisible(true);
		} else {
			confirmBid.setVisible(false);
		}
	}

	public void initSearchPanel() {
		// Widgets initialiseren
		Button refreshDock = new Button();
		Button backToList = new Button();
		HorizontalPanel dockNorth = new HorizontalPanel();
		HorizontalPanel dockSouth = new HorizontalPanel();
		VerticalPanel dockWest = new VerticalPanel();
		VerticalPanel dockEast = new VerticalPanel();
		DockPanel dockPanel2 = new DockPanel();
		FlexTable dockWestTimes = new FlexTable();
		FlexTable dockWestYourBid = new FlexTable();
		FlexCellFormatter cellFormatter = dockWestYourBid
				.getFlexCellFormatter();
		FlexTable dockEastInfo = new FlexTable();

		bidsOfProduct = null;
		bidsOfProduct = new ArrayList<Bid>();
		bidsTable = null;
		bidsTable = new CellTable<Bid>();

		bidsTable.setWidth("100%", true);
		bidsTable.setTableLayoutFixed(true);

		TextColumn<Bid> bidColumn = new TextColumn<Bid>() {
			@Override
			public String getValue(Bid object) {
				return String.valueOf(object.getBid());
			}
		};
		bidsTable.addColumn(bidColumn, "Bod");
		bidsTable.setColumnWidth(bidColumn, "30%");

		TextColumn<Bid> bidTimeColumn = new TextColumn<Bid>() {
			@Override
			public String getValue(Bid object) {
				String time = dtf.format(object.getBidTime());
				return time;
			}
		};
		bidsTable.addColumn(bidTimeColumn, "Bodtijd");
		bidsTable.setColumnWidth(bidTimeColumn, "40%");

		TextColumn<Bid> userIDColumn = new TextColumn<Bid>() {
			@Override
			public String getValue(Bid object) {
//				return String.valueOf(object.getUserID());
				return object.getUserName();
			}
		};

		bidsTable.addColumn(userIDColumn, "Bieder");
		bidsTable.setColumnWidth(userIDColumn, "30%");

		bidsTable.setRowCount(bidsOfProduct.size(), true);

		dockWest.setWidth("350px");
		dockWest.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		dockWest.add(new Image("images/product_bidtitle.png"));

		dockWestTimes.setWidget(0, 0, new Label("Begintijd:"));
		dockWestTimes.setWidget(1, 0, new Label("Eindtijd:"));
		dockWestTimes.setWidget(0, 1, startDate);
		dockWestTimes.setWidget(1, 1, endDate);

		dockWest.add(dockWestTimes);
		dockWest.add(new Label(" --- "));
		dockWest.add(new Label("Huidig bod:"));

		dockWest.add(highestBid);

		scroll.clear();
		scroll.setHeight("200px");
		scroll.add(bidsTable);

		dockWest.add(new Label(" --- "));
		dockWest.add(new Label("Biedgeschiedenis:"));
		dockWest.add(scroll);
		dockWest.add(new Label(" --- "));
		
		dockWestYourBid.setHTML(0, 0, "Plaats bod op product:");
		
		cellFormatter.setColSpan(0, 0, 2);
		cellFormatter.setHorizontalAlignment(0, 0,
				HasHorizontalAlignment.ALIGN_CENTER);
		dockWestYourBid.setWidget(1, 0, new Label("Credits"));
		dockWestYourBid.setWidget(1, 1, dockWestYourBidTextBox);
		
		if(user.isLoggedIn()){
			dockWest.add(dockWestYourBid);
		}

		dockEast.setWidth("600px");
		dockEast.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		dockEast.add(new Image("images/product_aboutproducttitle.png"));

		dockEastInfo.setWidget(0, 0, new Label("- ID:"));
		dockEastInfo.setWidget(1, 0, new Label("- Naam:"));
		dockEastInfo.setWidget(2, 0, new Label("- Beschrijving:"));
		dockEastInfo.setWidget(3, 0, new Label("- Categorie:"));
		dockEastInfo.setWidget(4, 0, new Label("- Aanbieder:"));
		dockEastInfo.setWidget(0, 1, productId);
		dockEastInfo.setWidget(1, 1, productName);
		dockEastInfo.setWidget(2, 1, productDescription);
		dockEastInfo.setWidget(3, 1, productCategory);
		dockEastInfo.setWidget(4, 1, productUserId);
		dockEast.add(dockEastInfo);
		// dockEast.add(new Image(imageURL));

		confirmBid.setText("Bod plaatsen");
		refreshDock.setText("Vernieuwen");
		backToList.setText("Terug naar overzicht");

		confirmBid.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				placeBid();
			}
		});

		refreshDock.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				findProductRPCcall(product.getProductID());
			}
		});

		backToList.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				History.newItem("home");
			}
		});

		dockSouth.clear();
		dockSouth.add(confirmBid);
		dockSouth.add(refreshDock);
		dockSouth.add(backToList);

		dockPanel2.clear();
		dockPanel2.add(dockNorth, DockPanel.NORTH);
		dockPanel2.add(dockSouth, DockPanel.SOUTH);
		dockPanel2.add(dockWest, DockPanel.WEST);
		dockPanel2.add(dockEast, DockPanel.EAST);
		dockPanel2.setCellHorizontalAlignment(dockNorth,
				HasHorizontalAlignment.ALIGN_CENTER);
		dockPanel2.setCellHorizontalAlignment(dockSouth,
				HasHorizontalAlignment.ALIGN_CENTER);

		vpContentData.clear();
		vpContentData.setWidth("100%");
		vpContentData
				.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		vpContentData.add(dockPanel2);
		vpContentData
				.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_DEFAULT);
		vp.clear();
		vpContentData.setSpacing(10);
		vp.add(vpContentData);
	}

	public void findProductRPCcall(int id) {
		ProductService.findSingleProduct(id, new AsyncCallback<Product>() {
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Product opvragen is mislukt");
			}

			@Override
			public void onSuccess(Product result) {
				setProduct(result);
				setVariables();
				findBidsRPCcall();
				findHighestBid();
			}
		});
	}

	public void findBidsRPCcall() {
		ProductService.findBidsOfProduct(product.getProductID(),
				new AsyncCallback<List<Bid>>() {
					@Override
					public void onFailure(Throwable caught) {
						Window.alert("Er is een fout opgetreden bij het opvragen van de boden, helaas.");
					}

					@Override
					public void onSuccess(List<Bid> result) {
						if (result.isEmpty()) {

						} else {
							bidsTable.setRowData(result);
						}
					}
				});
	}

	public void placeBid() {
		if (dockWestYourBidTextBox.getText().matches("^.{1,9}$")) {
			int bod = Integer.parseInt(dockWestYourBidTextBox.getText());
			if (bod > price && bod <= 999999) {
				if (product.getEndDate().after(new Date())) {
					if (product.getUserID() != user.getId()) {
						if(bod <= user.getCredits()){
							Bid b = new Bid(0, bod, product.getProductID(),
									user.getId(), new Date());
							ProductService.createNewBid(b,
									new AsyncCallback<Boolean>() {
	
										@Override
										public void onFailure(Throwable caught) {
											Window.alert("faal");
	
										}
	
										@Override
										public void onSuccess(Boolean result) {
											if (result) {
												Window.alert("Bod geplaatst");
												findProductRPCcall(product.getProductID());
											} else {
												Window.alert("We hebben je bod niet kunnen plaatsen");
											}
										}
									});
						}else{
							Window.alert("U heeft onvoldoende credits!");
						}
					} else {
						Window.alert("Kan niet op eigen product bieden.");
					}
				} else {
					Window.alert("Bied tijd verstreken.");
				}
			}
		}
	}

	public void findHighestBid() {
		price = product.getMinimumPrize();
		ProductService.getHighestBid(product.getProductID(),
				new AsyncCallback<Integer>() {
					@Override
					public void onFailure(Throwable caught) {
						Window.alert("Error with the bids");
						highestBid.setText(price + "");
						dockWestYourBidTextBox.setText("" + (price + 1));
					}

					@Override
					public void onSuccess(Integer result) {
						if (result > price) {
							price = result;
						}
						highestBid.setText(price + "");
						dockWestYourBidTextBox.setText("" + (price + 1));
					}
				});
	}

	public void setVariables() {
		productId.setText(product.getProductID() + "");
		productName.setText(product.getName());
		productDescription.setText(product.getDescription());
		productCategory.setText(product.getCategory());
		productUserId.setText(product.getUserName());
		String datetimeformated = dtf.format(product.getStartDate());
		startDate.setText(datetimeformated);
		if (product.getEndDate().after(new Date())) {
			String date = dtf.format(product.getEndDate());
			endDate.setText(date);
			confirmBid.setEnabled(true);
		} else {
			endDate.setText("Bied tijd verstreken.");
			confirmBid.setEnabled(false);
		}
	}

	public void getProduct(String id) {
		if (id.matches("^[0-9]{1,10}$")) {
			int productID = Integer.parseInt(id);
			findProductRPCcall(productID);
		}
	}

	public void setProduct(Product p) {
		this.product = p;
	}
}